package core_library

import (
	"fmt"
	"gin-api-server/core_library/library/cron"
	"gin-api-server/core_library/library/snowflake"
	"gin-api-server/core_library/library/systemlog"
	"go.uber.org/zap"
	"log"
	"os"
	"os/signal"
	"sync"

	"gin-api-server/core_library/global"
	"gin-api-server/core_library/library"
	"gin-api-server/core_library/library/cache"
	"gin-api-server/core_library/library/db"
	"gin-api-server/core_library/library/webengine"
	"gin-api-server/core_library/library/wx"
	"gin-api-server/utils/path"

	"github.com/fatih/color"
)

func init() {
	global.RootPath = path.GetRootPath()

}

func Main(configFile string) {
	library.ReloadConfig(configFile)

	// 把这些系统初始化任务异步设置为异步操作
	wg := sync.WaitGroup{}
	wg.Add(6)
	errChan := make(chan os.Signal, 1)
	signal.Notify(errChan, os.Interrupt)
	go func() {
		if err := initDataBase(); err != nil {
			log.Printf("数据库初始化失败: %v\n", err)
			errChan <- os.Interrupt
		}
		wg.Done()
	}()
	defer closeDataBase()

	go func() {
		if err := cache.InitRedisPool(); err != nil {
			log.Printf("Redis连接失败: %v\n", err)
			errChan <- os.Interrupt
		}
		wg.Done()
	}()
	defer closeRedis()

	go func() {
		snowflake.Start()
		wg.Done()
	}()
	go func() {
		cron.InitCron()
		wg.Done()
	}()

	go func() {
		if err := wx.InitWxMiniapp(); err != nil {
			log.Printf("微信小程序初始化失败: %v\n", err)
			errChan <- os.Interrupt
		}
		wg.Done()
	}()

	go func() {
		if err := wx.InitWxMp(); err != nil {
			log.Printf("微信公众号初始化失败: %v\n", err)
			errChan <- os.Interrupt
		}
		wg.Done()

	}()

	select {
	case <-errChan:
		log.Fatalf("系统启动失败...")
	case <-func() chan struct{} {
		done := make(chan struct{})
		go func() {
			wg.Wait()
			close(done)
		}()
		return done
	}():
		log.Println("加载完成...")

	}

	logger, err := systemlog.NewAsyncFileLogger("")
	if err != nil {
		log.Fatalf("日志初始化失败: %v\n", err)
		return
	}
	global.ZAP = logger
	defer func(logger *zap.Logger) {
		_ = logger.Sync()
	}(logger)

	// 加载web引擎
	webengine.InitGin()

}

func initDataBase() error {
	databaseDriver := global.Config.DataBase.ENGINE
	switch databaseDriver {
	case "mysql":
		err := db.InitMysql()
		if err != nil {
			return err
		}
	}
	return nil
}

func closeDataBase() {
	databaseDriver := global.Config.DataBase.ENGINE
	switch databaseDriver {
	case "mysql":
		if err := db.SqlDb.Close(); err != nil {
			fmt.Printf("断开与mysql的连接失败: %v\n", err)
		} else {
			color.Green("断开与mysql的连接")
		}
	}
}

func closeRedis() {
	if err := global.Redis.Close(); err != nil {
		fmt.Printf("断开与redis的连接失败: %v\n", err)
	} else {
		color.Green("断开与redis的连接")
	}
}
